package com.motu.monstercity.server.game.logic;

import com.motu.monstercity.server.game.commondata.act.ActConvention;
import com.motu.monstercity.server.game.commondata.act.ActConventionTask;
import com.motu.vertx.module.utility.mysql.MysqlClient;
import com.motu.vertx.module.utility.mysql.MysqlTool;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class ActConventionBaseData {
    private static Logger logger = LoggerFactory.getLogger(ActConventionBaseData.class);
    private static ConcurrentHashMap<Integer, ActConvention> actConventionMap = new ConcurrentHashMap<>(); // 万能活动配置表<活动ID，活动配置>

    private static ConcurrentHashMap<Integer, ActConventionTask> actConventionTaskMap = new ConcurrentHashMap<>(); // 万能活动任务配置表
    private static ConcurrentHashMap<Integer, List<ActConventionTask>> actConventionTaskGroupMap = new ConcurrentHashMap<>(); // 万能活动任务配置表<活动分组ID，任务列表>


    public static void initBaseData(List<Future> futures) {
        futures.add(initActConvention());
        futures.add(initActConventionTask());
    }


    /**
     * 初始化万能活动配置表
     */
    public static Future<Void> initActConvention() {
        String table = "act_convention";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, ActConvention> tmp = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        ActConvention entity = new ActConvention(result.getJsonObject(i));
                        tmp.put(entity.getId(), entity);
                    }
                    actConventionMap = tmp;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static ActConvention getActConvention(int id) {
        ActConvention result = actConventionMap.get(id);
        if (result == null) {
            logger.error("getActConvention error key = " + id);
        }
        return result;
    }
    public static ConcurrentHashMap<Integer, ActConvention> getActConventionMap() { return actConventionMap; }



    /**
     * 初始化万能活动任务配置表
     */
    public static Future<Void> initActConventionTask() {
        String table = "act_convention_task";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, ActConventionTask> tmp = new ConcurrentHashMap<>();
                    ConcurrentHashMap<Integer, List<ActConventionTask>> tmpGroup = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        ActConventionTask entity = new ActConventionTask(result.getJsonObject(i));
                        tmpGroup.computeIfAbsent(entity.getTaskGroupId(), k -> new ArrayList<>()).add(entity);
                        tmp.put(entity.getId(), entity);
                    }
                    actConventionTaskMap = tmp;
                    actConventionTaskGroupMap = tmpGroup;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static ActConventionTask getActConventionTask(int id) {
        ActConventionTask result = actConventionTaskMap.get(id);
        if (result == null) {
            logger.error("getActConventionTask error key = " + id);
        }
        return result;
    }
    public static ConcurrentHashMap<Integer, ActConventionTask> getActConventionTaskMap() { return actConventionTaskMap; }

    public static List<ActConventionTask> getActConventionTasksByGroupId(int groupId) {
        List<ActConventionTask> taskList = actConventionTaskGroupMap.get(groupId);
        if (taskList == null || taskList.isEmpty()) {
            return null;
        }
        return taskList;
    }

    public static List<ActConventionTask> getActConventionTasksByGroupIdAndType(int groupId, int type) {
        List<ActConventionTask> taskList = actConventionTaskGroupMap.get(groupId);
        if (taskList == null || taskList.isEmpty()) {
            return null;
        }
        return taskList.stream().filter(t -> t.getTaskType() == type).toList();
    }

    public static ActConventionTask getActConventionTasksByTaskTypeId(int taskTypeId) {
        for (ActConventionTask task : actConventionTaskMap.values()) {
            int newTaskTypeId = getTaskId(task.getTaskType(), task.getNum2());
            if (newTaskTypeId == taskTypeId) { // 如果多个分组中有相同的任务类型ID，重置类型不一样的会有问题，需要修改
                return task;
            }
        }
        return null;
    }

    public static int getTaskId(int taskType, int param) {
        if (param == 0) {
            return taskType;
        }
        return taskType * 1000000 + param;
    }
}
